# -*- coding: utf-8 -*-
#
# Copyright (c) 2025 Huawei Technologies Co., Ltd.
# openUBMC is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#         http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.

"""
文件结构生成器

负责生成 C++ 文件的整体结构（头文件保护、includes 等）
"""

from typing import List, Set
from ..ir import IRModule


class FileStructureGenerator:
    """文件结构生成器"""

    @staticmethod  # type: ignore
    def generate_header_guard(module_name: str) -> str:
        """生成头文件保护

        Args:
            module_name: 模块名称

        Returns:
            头文件保护宏定义
        """
        guard_name = f"MC_{module_name.upper()}_H"
        return f"#ifndef {guard_name}\n#define {guard_name}"

    @staticmethod  # type: ignore
    def generate_header_guard_end(module_name: str) -> str:
        """生成头文件保护结束

        Args:
            module_name: 模块名称

        Returns:
            头文件保护结束
        """
        guard_name = f"MC_{module_name.upper()}_H"
        return f"#endif // {guard_name}"

    @staticmethod  # type: ignore
    def format_includes(includes: Set[str]) -> str:
        """格式化 includes

        Args:
            includes: include 可迭代对象（列表、集合等）

        Returns:
            格式化后的 include 代码
        """
        lines = []
        for include in includes:
            if include.startswith("<") and include.endswith(">"):
                # 已经是完整格式：<header.h>
                lines.append(f"#include {include}")
            elif include.startswith('"') and include.endswith('"'):
                # 已经是完整格式："header.h"
                lines.append(f"#include {include}")
            else:
                # 需要添加尖括号：header.h -> <header.h>
                lines.append(f"#include <{include}>")
        return "\n".join(lines)

    @staticmethod  # type: ignore
    def generate_header_file(
        ir_module: "IRModule",
        module_name: str,
        nodes_content: str,
        lambda_structs: List[str],
    ) -> str:
        """生成完整的头文件内容

        Args:
            ir_module: IR 模块
            module_name: 模块名称
            nodes_content: 节点内容（已生成的代码）
            lambda_structs: lambda 结构体列表

        Returns:
            完整的头文件内容
        """
        lines = []

        # 头文件保护开始
        lines.append(FileStructureGenerator.generate_header_guard(module_name))
        lines.append("")

        # Includes
        includes = ir_module.get_includes()
        if includes:
            includes_code = FileStructureGenerator.format_includes(includes)
            lines.append(includes_code)
            lines.append("")

        # 节点内容
        if nodes_content.strip():
            lines.append(nodes_content)
            if not nodes_content.endswith("\n"):
                lines.append("")

        # Lambda 结构体定义
        if lambda_structs:
            lines.append("// Lambda 结构体定义")
            for struct in lambda_structs:
                lines.append(struct)
                if not struct.endswith("\n"):
                    lines.append("")

        # 头文件保护结束
        lines.append(FileStructureGenerator.generate_header_guard_end(module_name))

        return "\n".join(lines)

    @staticmethod  # type: ignore
    def generate_source_file(
        header_file: str,
        includes: Set[str],
        nodes_content: str,
    ) -> str:
        """生成完整的源文件内容

        Args:
            header_file: 头文件名
            includes: include 集合
            nodes_content: 节点内容（已生成的代码）

        Returns:
            完整的源文件内容
        """
        lines = []

        # 包含对应的头文件
        if header_file:
            lines.append(f'#include "{header_file}"')
            lines.append("")

        # 其他 includes
        if includes:
            includes_code = FileStructureGenerator.format_includes(includes)
            lines.append(includes_code)
            lines.append("")

        # 节点内容
        if nodes_content.strip():
            lines.append(nodes_content)

        return "\n".join(lines)
